package de.lulusoft.anothertorrent.gui.views;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.progress.UIJob;

import de.lulusoft.anothertorrent.core.AnotherTorrentCore;
import de.lulusoft.anothertorrent.core.rtorrent.File;
import de.lulusoft.anothertorrent.core.rtorrent.Peer;
import de.lulusoft.anothertorrent.core.rtorrent.Torrent;
import de.lulusoft.anothertorrent.core.rtorrent.Tracker;
import de.lulusoft.anothertorrent.core.servers.Server;
import de.lulusoft.anothertorrent.gui.AnotherTorrentGui;
import de.lulusoft.anothertorrent.gui.commands.FileSetPriorityCommand;
import de.lulusoft.anothertorrent.gui.commands.TrackerChangeEnabledCommand;
import de.lulusoft.anothertorrent.gui.preferences.PreferenceConstants;
import de.lulusoft.anothertorrent.gui.util.Util;
import de.lulusoft.anothertorrent.gui.views.Providers.FilesTableContentProvider;
import de.lulusoft.anothertorrent.gui.views.Providers.FilesTableLabelProvider;
import de.lulusoft.anothertorrent.gui.views.Providers.PeersTableContentProvider;
import de.lulusoft.anothertorrent.gui.views.Providers.PeersTableLabelProvider;
import de.lulusoft.anothertorrent.gui.views.Providers.TableColumnSorter;
import de.lulusoft.anothertorrent.gui.views.Providers.TorrentDetailsViewInput;
import de.lulusoft.anothertorrent.gui.views.Providers.TrackerTableContentProvider;
import de.lulusoft.anothertorrent.gui.views.Providers.TrackerTableLabelProvider;

public class TorrentDetailsView extends ViewPart {
	
	public static final String ID = "de.lulusoft.anothertorrent.gui.views.TorrentDetailsView";
	
	private static final String STATE_INPUT = "STATE_INPUT";
	
	private Job timer = null;
	private TorrentDetailsViewInput m_input = null;
	
	// Main Widgets
	private TabFolder tabs = null;
		
	// Info Widgets
	private Text infoName = null;
	private Text infoUpRate = null;
	private Text infoDownRate = null;
	private Text infoPeers = null;
	private Text infoSize = null;
	private Text infoFreeDiskSpace = null;
	private Text infoPath = null;
	private Text infoHash = null;
	private Text infoConnectionType = null;
	private Text infoMessage = null;
	
	
	// Files Widgets
	private TableViewer tableFiles = null;
	private static final String[] fileProperties = {"Filename", "Size", "Done", "Chunks", "Priority"}; 
		
	// Peers Widgets
	private TableViewer tablePeers = null;
	private static final String[] peersProperties = {"Address", "Client", "Complete", "Download", "Upload", "Peer", "Encrypted", "Obfuscated", "Incoming", "Snubbed", "Options", "Id"};
	
	// Tracker Widgets
	private TableViewer tableTracker = null;
	private static final String[] trackerProperties = {"URL", "Last", "Interval", "Scraped", "Enabled", "Group", "Id", "Type", "Open"}; 
	
	public TorrentDetailsView() {
	}
	
	@Override
	public void dispose() {
		if (timer != null)
			timer.cancel();
		super.dispose();
	}
	
	@Override
	public void saveState(IMemento memento) {
		super.saveState(memento);
		ByteArrayOutputStream  os = new ByteArrayOutputStream();
		ObjectOutputStream oOut = null;
		try {
			oOut = new ObjectOutputStream(os);
			oOut.writeObject(m_input);
			oOut.flush();
			String tmp = Util.convertBytesToHex(os.toByteArray());
			memento.putString(STATE_INPUT, tmp);
		} catch (IOException e) {
			e.printStackTrace();
		} finally 
		{
			try {
				oOut.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}	

	@Override
	public void init(IViewSite site, IMemento memento) throws PartInitException {
		super.init(site, memento);
		if (memento == null)
			return;
		String state = memento.getString(STATE_INPUT);
		if (state != null)
		{
			try {
				byte bstate[] = Util.convertHexStringToBytes(state);
				ByteArrayInputStream is = new ByteArrayInputStream(bstate);
				ObjectInputStream ois = new ObjectInputStream(is);
				TorrentDetailsViewInput input = (TorrentDetailsViewInput) ois.readObject();
				Server server = AnotherTorrentCore.getDefault().getServerManager().getServerByName(input.getServer().getName());
				input = new TorrentDetailsViewInput(server,	input.getTorrent());
				this.m_input = input;
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
	}

	public void setInput(Object input)
	{
		if (input instanceof TorrentDetailsViewInput
				&& !tableFiles.getTable().isDisposed()
				&& !tablePeers.getTable().isDisposed()
				&& !tableTracker.getTable().isDisposed())
		{
			timer.cancel();
			
			try
			{
			
				m_input = (TorrentDetailsViewInput) input;
				this.setPartName(m_input.getTorrent().getName());
				
				// Display info
				updateInfoTab(m_input.getTorrent());
				
				// Get Files
				m_input.getServer().getRTorrentManager().getFiles(m_input.getTorrent());
				tableFiles.setInput(m_input.getTorrent().getFiles());
				for (TableColumn tc : tableFiles.getTable().getColumns())
					tc.pack();
				
				// Get Peers
				m_input.getServer().getRTorrentManager().getPeers(m_input.getTorrent());
				tablePeers.setInput(m_input.getTorrent().getPeers());
				for (TableColumn tc : tablePeers.getTable().getColumns())
					tc.pack();
				
				// Get Trackers
				m_input.getServer().getRTorrentManager().getTrackers(m_input.getTorrent());
				tableTracker.setInput(m_input.getTorrent().getTrackers());
				for (TableColumn tc : tableTracker.getTable().getColumns())
					tc.pack();
				
				timer.schedule(AnotherTorrentGui.getDefault()
						.getPreferenceStore().getInt(PreferenceConstants.P_UPDATE_INTERVAL_DETAILS_VIEW) * 1000);
			} catch (Exception e) {
				IStatus status = new Status(IStatus.ERROR, AnotherTorrentGui.PLUGIN_ID, "Could not set input on TorrentDetailsView", e);
				AnotherTorrentGui.getDefault().getLog().log(status );
				e.printStackTrace();
			}
			
		}
		
	}
	
	public void updateInfoTab(Torrent t)
	{
		if (!infoName.getText().equals(t.getBase_filename()))
			infoName.setText(t.getBase_filename());
		if (!infoHash.getText().equals(t.getHash()))
			infoHash.setText(t.getHash());
		if (!infoUpRate.getText().equals(Util.formatBytes(t.getUp_rate())))
			infoUpRate.setText(Util.formatBytes(t.getUp_rate()));
		if (!infoDownRate.getText().equals(Util.formatBytes(t.getDown_rate())))
			infoDownRate.setText(Util.formatBytes(t.getDown_rate()));
		if (!infoPeers.getText().equals(t.getPeers_connected() + " / " + t.getPeers_not_connected() + " / " + t.getPeers_complete() + " / " + t.getPeers_accounted()))
			infoPeers.setText(t.getPeers_connected() + " / " + t.getPeers_not_connected() + " / " + t.getPeers_complete() + " / " + t.getPeers_accounted());
		if (!infoSize.getText().equals(Util.formatBytes(t.getSize_bytes())))
			infoSize.setText(Util.formatBytes(t.getSize_bytes()));
		if (!infoFreeDiskSpace.getText().equals(Util.formatBytes(t.getFree_diskspace())))
			infoFreeDiskSpace.setText(Util.formatBytes(t.getFree_diskspace()));
		if (!infoPath.getText().equals(t.getBase_path()))
			infoPath.setText(t.getBase_path());
		if (!infoConnectionType.getText().equals(t.getConnection_current()))
			infoConnectionType.setText(t.getConnection_current());
		if (!infoMessage.getText().equals(t.getMessage()))
			infoMessage.setText(t.getMessage());
	}

	@Override
	public void createPartControl(Composite parent) {
		
		// Create TabFolders
		tabs = new TabFolder(parent, SWT.BORDER);
		TabItem main = new TabItem (tabs, SWT.NONE);
		main.setText("Info");
		TabItem files = new TabItem (tabs, SWT.NONE);
		files.setText("Files");
		TabItem peers = new TabItem (tabs, SWT.NONE);
		peers.setText("Peers");
		TabItem trackers = new TabItem (tabs, SWT.NONE);
		trackers.setText("Tracker");
		
		
		// Create Tab Contents
		files.setControl(createFilesTab(tabs));
		peers.setControl(createPeersTab(tabs));
		trackers.setControl(createTrackerTab(tabs));
		main.setControl(createInfoTab(tabs));
		
		// create timer
		timer = new Job("Update Torrent Details Data"){
		
			@Override
			protected IStatus run(IProgressMonitor monitor) {

				monitor.beginTask("Updating Torrent Details Data", IProgressMonitor.UNKNOWN);
				try {
					m_input.getServer().getRTorrentManager().updateFiles(m_input.getTorrent());
					m_input.getServer().getRTorrentManager().updatePeers(m_input.getTorrent());
					m_input.getServer().getRTorrentManager().updateTrackers(m_input.getTorrent());
					m_input.getServer().getRTorrentManager().updateTorrent(m_input.getTorrent());
				} catch (Exception e) {
					IStatus status = new Status(IStatus.ERROR, AnotherTorrentGui.PLUGIN_ID, "Could not update Torrent Details Data", e);
					AnotherTorrentGui.getDefault().getLog().log(status );
					e.printStackTrace();
				}
				
				
				UIJob ui = new UIJob(Display.getDefault(), "Update Torrent Details") {
					@Override
					public IStatus runInUIThread(IProgressMonitor monitor) {
						monitor.beginTask("Updating Torrent " + m_input.getTorrent().getName(), IProgressMonitor.UNKNOWN);
						// Save current selection, update gui, restore selection
						ISelection sel = tableFiles.getSelection();
						m_input.getTorrent().getFiles().updateGUI();
						tableFiles.setSelection(sel, false);
						
						sel = tablePeers.getSelection();
						m_input.getTorrent().getPeers().updateGUI();
						tablePeers.setSelection(sel, false);
						
						sel = tableTracker.getSelection();
						m_input.getTorrent().getTrackers().updateGUI();
						tableTracker.setSelection(sel, false);
						
						updateInfoTab(m_input.getTorrent());
						monitor.done();
						return Status.OK_STATUS;
					}
				};
				ui.setUser(false);
				ui.schedule();
				timer.schedule(AnotherTorrentGui.getDefault()
						.getPreferenceStore().getInt(PreferenceConstants.P_UPDATE_INTERVAL_DETAILS_VIEW) * 1000);
				monitor.done();
				return Status.OK_STATUS;
			}
		};
		timer.setUser(false);
		
		// restore view if input is available
		if (this.m_input != null)
			this.setInput(this.m_input);		
		
	}

	private Composite createInfoTab(Composite parent)
	{
		Composite main = new Composite(parent, SWT.NONE);
		main.setLayout(new GridLayout(2, false));
		GridData gd = new GridData();
		gd.grabExcessHorizontalSpace = true;
		gd.grabExcessVerticalSpace = false;
		gd.verticalAlignment = SWT.FILL;
		gd.horizontalAlignment = SWT.FILL;
		
		Label  lInfoName = new Label(main, SWT.NONE);
		lInfoName.setLayoutData(gd);
		lInfoName.setText("Name: ");
		infoName = new Text(main, SWT.SINGLE | SWT.READ_ONLY);
		infoName.setLayoutData(gd);
		
		Label  lInfoHash = new Label(main, SWT.NONE);
		lInfoHash.setLayoutData(gd);
		lInfoHash.setText("Hash: ");
		infoHash = new Text(main, SWT.SINGLE | SWT.READ_ONLY);
		infoHash.setLayoutData(gd);
		
		Label  linfoPath = new Label(main, SWT.NONE);
		linfoPath.setLayoutData(gd);
		linfoPath.setText("Path: ");
		infoPath = new Text(main, SWT.SINGLE | SWT.READ_ONLY);
		infoPath.setLayoutData(gd);
		
		Label  linfoSize = new Label(main, SWT.NONE);
		linfoSize.setLayoutData(gd);
		linfoSize.setText("Size: ");
		infoSize = new Text(main, SWT.SINGLE | SWT.READ_ONLY);
		infoSize.setLayoutData(gd);
		
		Label  linfoFreeDiskSpace = new Label(main, SWT.NONE);
		linfoFreeDiskSpace.setLayoutData(gd);
		linfoFreeDiskSpace.setText("Free Disk Space: ");
		infoFreeDiskSpace = new Text(main, SWT.SINGLE | SWT.READ_ONLY);
		infoFreeDiskSpace.setLayoutData(gd);
		
		Label  linfoDownRate = new Label(main, SWT.NONE);
		linfoDownRate.setLayoutData(gd);
		linfoDownRate.setText("DownRate: ");
		infoDownRate = new Text(main, SWT.SINGLE | SWT.READ_ONLY);
		infoDownRate.setLayoutData(gd);
		
		Label  linfoUpRate = new Label(main, SWT.NONE);
		linfoUpRate.setLayoutData(gd);
		linfoUpRate.setText("UpRate: ");
		infoUpRate = new Text(main, SWT.SINGLE | SWT.READ_ONLY);
		infoUpRate.setLayoutData(gd);
		
		Label  linfoPeers = new Label(main, SWT.NONE);
		linfoPeers.setLayoutData(gd);
		linfoPeers.setText("Peers (Connected/NotCon/Complete/Accounted): ");
		infoPeers = new Text(main, SWT.SINGLE | SWT.READ_ONLY);
		infoPeers.setLayoutData(gd);
		
		Label  linfoConnectionType = new Label(main, SWT.NONE);
		linfoConnectionType.setLayoutData(gd);
		linfoConnectionType.setText("Connection type:");
		infoConnectionType = new Text(main, SWT.SINGLE | SWT.READ_ONLY);
		infoConnectionType.setLayoutData(gd);
		
		Label  linfoMessage = new Label(main, SWT.NONE);
		linfoMessage.setLayoutData(gd);
		linfoMessage.setText("Message:");
		infoMessage = new Text(main, SWT.SINGLE | SWT.READ_ONLY);
		infoMessage.setLayoutData(gd);
		
		return main;
	}
	
	private Composite createFilesTab(Composite parent)
	{
		Composite main = new Composite(parent, SWT.NONE);
		main.setLayout(new GridLayout(1,true));
		GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false);
		Composite toolbar = new Composite(main, SWT.FILL);
		toolbar.setLayoutData(gd);
		toolbar.setLayout(new RowLayout());
		
		final Menu mnuSetPrio = new Menu(toolbar.getParent().getShell(), SWT.POP_UP);
		MenuItem miOff = new MenuItem(mnuSetPrio, SWT.NONE);
		miOff.setText("Off");
		miOff.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)tableFiles.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<File> it = sel.iterator();
					while (it.hasNext())
					{
						File t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(FileSetPriorityCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(FileSetPriorityCommand.P_PRIORITY, "0");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		MenuItem miNormal = new MenuItem(mnuSetPrio, SWT.NONE);
		miNormal.setText("Normal");
		miNormal.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)tableFiles.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<File> it = sel.iterator();
					while (it.hasNext())
					{
						File t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(FileSetPriorityCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(FileSetPriorityCommand.P_PRIORITY, "1");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		MenuItem miHigh = new MenuItem(mnuSetPrio, SWT.NONE);
		miHigh.setText("High");
		miHigh.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)tableFiles.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<File> it = sel.iterator();
					while (it.hasNext())
					{
						File t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(FileSetPriorityCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(FileSetPriorityCommand.P_PRIORITY, "2");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});		
		final Button cmdSetPrio = new Button(toolbar, SWT.PUSH | SWT.DROP_DOWN);
		cmdSetPrio.setText("Set Priority");
		cmdSetPrio.addSelectionListener(new SelectionListener(){

			public void widgetDefaultSelected(SelectionEvent e) {}

			public void widgetSelected(SelectionEvent e) {
				if ( !mnuSetPrio.isVisible() ) {
					Rectangle bounds = cmdSetPrio.getBounds();
					Point menuLoc =
						cmdSetPrio.getParent().toDisplay(bounds.x, bounds.y + bounds.height);

					mnuSetPrio.setLocation(menuLoc.x, menuLoc.y);
					mnuSetPrio.setVisible(true);
				}
			}			
		});
		
		Composite viewerComp = new Composite(main, SWT.FILL | SWT.BORDER);
		gd = new GridData(SWT.FILL, SWT.FILL, true, true);
		viewerComp.setLayoutData(gd);
		viewerComp.setLayout(new FillLayout());
		tableFiles = new TableViewer(viewerComp, SWT.FULL_SELECTION | SWT.MULTI);
		tableFiles.getTable().setHeaderVisible(true);
		tableFiles.getTable().setLinesVisible(true);		
		int i = 0;
		for (final String prop : fileProperties)
		{
			final int colIdx = i;
			TableViewerColumn column = new TableViewerColumn(tableFiles, SWT.NONE);
			column.getColumn().setText(prop);
			column.getColumn().setWidth(100);
			column.getColumn().setMoveable(true);

			TableColumnSorter cSorter = new TableColumnSorter(tableFiles, column.getColumn()) 
			{
			     protected int doCompare(Viewer v, Object e1, Object e2) 
			     {
			    	 File t1 = (File)e1;
			    	 File t2 = (File)e2;
			    	 if (prop.equals("Size"))
			    	 {
			    		return t1.getSize_bytes().compareTo(t2.getSize_bytes()); 
			    	 }
			    	 else if (prop.equals("Done"))
			    	 {
			    		return t1.getDonePercent().compareTo(t2.getDonePercent()); 
			    	 }
			      	 else if (prop.equals("Priority"))
			    	 {
			    		return t1.getPriority().compareTo(t2.getPriority()); 
			    	 }
			    	 else
			    	 {
			             ITableLabelProvider lp = ((ITableLabelProvider) tableFiles
			            		 .getLabelProvider());
			             String s1 = lp.getColumnText(e1, colIdx);
			             String s2 = lp.getColumnText(e2, colIdx);
			             return s1.compareTo(s2);
			    	 }
			     }
			};

			cSorter.setSorter(cSorter, TableColumnSorter.ASC);
			i++;
		}		
		tableFiles.setContentProvider(new FilesTableContentProvider());
		tableFiles.setLabelProvider(new FilesTableLabelProvider());
		
		// Create viewer context menu
		// Create popup menu
		final Menu mnuContext = new Menu(tableFiles.getTable().getParent().getShell(), SWT.POP_UP);
		MenuItem itemPrioMenu = new MenuItem(mnuContext, SWT.CASCADE);
		itemPrioMenu.setText("Set Priority");
		Menu mnuContextPrio = new Menu(tableFiles.getTable().getParent().getShell(), SWT.DROP_DOWN);
		itemPrioMenu.setMenu(mnuContextPrio);
		MenuItem miContextPrioOff = new MenuItem(mnuContextPrio, SWT.NONE);
		miContextPrioOff.setText("Off");
		miContextPrioOff.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)tableFiles.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<File> it = sel.iterator();
					while (it.hasNext())
					{
						File t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(FileSetPriorityCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(FileSetPriorityCommand.P_PRIORITY, "0");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}		
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		MenuItem miContextPrioNormal = new MenuItem(mnuContextPrio, SWT.NONE);
		miContextPrioNormal.setText("Normal");
		miContextPrioNormal.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)tableFiles.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<File> it = sel.iterator();
					while (it.hasNext())
					{
						File t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(FileSetPriorityCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(FileSetPriorityCommand.P_PRIORITY, "1");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		MenuItem miContextPrioHigh = new MenuItem(mnuContextPrio, SWT.NONE);
		miContextPrioHigh.setText("High");
		miContextPrioHigh.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)tableFiles.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<File> it = sel.iterator();
					while (it.hasNext())
					{
						File t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(FileSetPriorityCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(FileSetPriorityCommand.P_PRIORITY, "2");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		tableFiles.getTable().setMenu(mnuContext);
		
		
		return main;
	}
	
	private Composite createPeersTab(Composite parent)
	{
		Composite main = new Composite(parent, SWT.NONE);
		main.setLayout(new FillLayout());
		tablePeers = new TableViewer(main, SWT.FULL_SELECTION | SWT.MULTI);
		tablePeers.getTable().setHeaderVisible(true);
		tablePeers.getTable().setLinesVisible(true);
		
		int i = 0;
		for (final String prop : peersProperties)
		{
			final int colIdx = i;
			TableViewerColumn column = new TableViewerColumn(tablePeers, SWT.NONE);
			column.getColumn().setText(prop);
			column.getColumn().setWidth(100);
			column.getColumn().setMoveable(true);

			TableColumnSorter cSorter = new TableColumnSorter(tablePeers, column.getColumn()) 
			{
			     protected int doCompare(Viewer v, Object e1, Object e2) 
			     {
			    	 Peer t1 = (Peer)e1;
			    	 Peer t2 = (Peer)e2;
			    	 if (prop.equals("Complete"))
			    	 {
			    		return t1.getCompleted_percent().compareTo(t2.getCompleted_percent()); 
			    	 }
			    	 else if (prop.equals("Download"))
			    	 {
			    		return t1.getDown_rate().compareTo(t2.getDown_rate()); 
			    	 }
			      	 else if (prop.equals("Upload"))
			    	 {
			    		return t1.getUp_rate().compareTo(t2.getUp_rate()); 
			    	 }
			    	 else
			    	 {
			             ITableLabelProvider lp = ((ITableLabelProvider) tablePeers
			            		 .getLabelProvider());
			             String s1 = lp.getColumnText(e1, colIdx);
			             String s2 = lp.getColumnText(e2, colIdx);
			             return s1.compareTo(s2);
			    	 }
			     }
			};

			cSorter.setSorter(cSorter, TableColumnSorter.ASC);
			i++;
		}
		
		tablePeers.setContentProvider(new PeersTableContentProvider());
		tablePeers.setLabelProvider(new PeersTableLabelProvider());
		
		
		return main;
	}
	
	private Composite createTrackerTab(Composite parent)
	{
		Composite main = new Composite(parent, SWT.NONE);
		main.setLayout(new GridLayout(1,true));
		GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false);
		Composite toolbar = new Composite(main, SWT.FILL);
		toolbar.setLayoutData(gd);
		toolbar.setLayout(new RowLayout());
		
		final Menu mnuSetEnabled = new Menu(toolbar.getParent().getShell(), SWT.POP_UP);
		MenuItem miDisable = new MenuItem(mnuSetEnabled, SWT.NONE);
		miDisable.setText("Disabled");
		miDisable.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)tableTracker.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Tracker> it = sel.iterator();
					while (it.hasNext())
					{
						Tracker t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(TrackerChangeEnabledCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(TrackerChangeEnabledCommand.P_ENABLED, "0");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		MenuItem miEnable = new MenuItem(mnuSetEnabled, SWT.NONE);
		miEnable.setText("Enabled");
		miEnable.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)tableTracker.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Tracker> it = sel.iterator();
					while (it.hasNext())
					{
						Tracker t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(TrackerChangeEnabledCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(TrackerChangeEnabledCommand.P_ENABLED, "1");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		final Button cmdSetEnabled = new Button(toolbar, SWT.PUSH | SWT.DROP_DOWN);
		cmdSetEnabled.setText("Set Enabled");
		cmdSetEnabled.addSelectionListener(new SelectionListener(){

			public void widgetDefaultSelected(SelectionEvent e) {}

			public void widgetSelected(SelectionEvent e) {
				if ( !mnuSetEnabled.isVisible() ) {
					Rectangle bounds = cmdSetEnabled.getBounds();
					Point menuLoc =
						cmdSetEnabled.getParent().toDisplay(bounds.x, bounds.y + bounds.height);

					mnuSetEnabled.setLocation(menuLoc.x, menuLoc.y);
					mnuSetEnabled.setVisible(true);
				}
			}			
		});
		
		Composite viewerComp = new Composite(main, SWT.FILL | SWT.BORDER);
		gd = new GridData(SWT.FILL, SWT.FILL, true, true);
		viewerComp.setLayoutData(gd);
		viewerComp.setLayout(new FillLayout());
		tableTracker = new TableViewer(viewerComp, SWT.FULL_SELECTION | SWT.MULTI);
		tableTracker.getTable().setHeaderVisible(true);
		tableTracker.getTable().setLinesVisible(true);
		int i = 0;
		for (final String prop : trackerProperties)
		{
			final int colIdx = i;
			TableViewerColumn column = new TableViewerColumn(tableTracker, SWT.NONE);
			column.getColumn().setText(prop);
			column.getColumn().setWidth(100);
			column.getColumn().setMoveable(true);

			TableColumnSorter cSorter = new TableColumnSorter(tableTracker, column.getColumn()) 
			{
			     protected int doCompare(Viewer v, Object e1, Object e2) 
			     {
//			    	 Tracker t1 = (Tracker)e1;
//			    	 Tracker t2 = (Tracker)e2;
			    	
		             ITableLabelProvider lp = ((ITableLabelProvider) tableTracker
		            		 .getLabelProvider());
		             String s1 = lp.getColumnText(e1, colIdx);
		             String s2 = lp.getColumnText(e2, colIdx);
		             return s1.compareTo(s2);
			     }
			};

			cSorter.setSorter(cSorter, TableColumnSorter.ASC);
			i++;
		}
		tableTracker.setContentProvider(new TrackerTableContentProvider());
		tableTracker.setLabelProvider(new TrackerTableLabelProvider());
		
		// Create viewer context menu
		// Create popup menu
		final Menu mnuContext = new Menu(tableTracker.getTable().getParent().getShell(), SWT.POP_UP);
		MenuItem itemEnabledMenu = new MenuItem(mnuContext, SWT.CASCADE);
		itemEnabledMenu.setText("Set Enabled");
		Menu mnuContextEnabled = new Menu(tableTracker.getTable().getParent().getShell(), SWT.DROP_DOWN);
		itemEnabledMenu.setMenu(mnuContextEnabled);
		MenuItem miContextDisabled = new MenuItem(mnuContextEnabled, SWT.NONE);
		miContextDisabled.setText("Disabled");
		miContextDisabled.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)tableTracker.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Tracker> it = sel.iterator();
					while (it.hasNext())
					{
						Tracker t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(TrackerChangeEnabledCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(TrackerChangeEnabledCommand.P_ENABLED, "0");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		MenuItem miContextEnabled = new MenuItem(mnuContextEnabled, SWT.NONE);
		miContextEnabled.setText("Enabled");
		miContextEnabled.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)tableTracker.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Tracker> it = sel.iterator();
					while (it.hasNext())
					{
						Tracker t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(TrackerChangeEnabledCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(TrackerChangeEnabledCommand.P_ENABLED, "1");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		tableTracker.getTable().setMenu(mnuContext);
		
		
		return main;
	}
	

	@Override
	public void setFocus() {
	}

}
